package com.zzyl.nursing.service.impl;

import ch.qos.logback.core.net.server.Client;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaweicloud.sdk.iotda.v5.IoTDAClient;
import com.huaweicloud.sdk.iotda.v5.model.ShowDeviceShadowRequest;
import com.huaweicloud.sdk.iotda.v5.model.ShowDeviceShadowResponse;
import com.zzyl.common.core.domain.AjaxResult;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.nursing.domain.Device;
import com.zzyl.nursing.domain.DeviceData;
import com.zzyl.nursing.domain.FamilyMemberElder;
import com.zzyl.nursing.dto.ByDayDto;
import com.zzyl.nursing.dto.DevicePropertyDto;
import com.zzyl.nursing.mapper.DeviceDataMapper;
import com.zzyl.nursing.mapper.FamilyMemberElderMapper;
import com.zzyl.nursing.service.IDeviceDataService;
import com.zzyl.nursing.service.IDeviceService;
import com.zzyl.nursing.service.IFamilyMemberElderService;
import com.zzyl.nursing.vo.DeviceDataByTime;
import org.aspectj.weaver.loadtime.Aj;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class FamilyMemberElderServiceImpl extends ServiceImpl<FamilyMemberElderMapper,FamilyMemberElder> implements IFamilyMemberElderService {
@Autowired
private FamilyMemberElderMapper familyMemberElderMapper;
@Autowired
private IDeviceService deviceService;
@Autowired
private RedisTemplate  redisTemplate;
@Autowired
private IoTDAClient client;

private static  Map<String,String> name=new HashMap<>();
private static  Map<String,String> unit=new HashMap<>();
private static  Map<String,String> type=new HashMap<>();

    static {
        name.put("BodyTemp", "体温");
        name.put("xueyang", "血氧");
        name.put("HeartRate", "心率");
        name.put("BatteryPercentage", "电池电量百分比");
        unit.put("BodyTemp", "℃");
        unit.put("BatteryPercentage", "%");
        unit.put("HeartRate", "");
        type.put("BodyTemp", "float");
        type.put("xueyang", "int");
        type.put("HeartRate", "int");
        type.put("BatteryPercentage", "double");

    }


    @Override
    public AjaxResult queryDevicePropertyStatus(DevicePropertyDto dto, HttpServletRequest request) {
        Device device= deviceService.lambdaQuery().eq(Device::getDeviceName,dto.getDeviceName()).eq(Device::getProductKey,dto.getProductKey()).one();
        if(ObjectUtil.isEmpty( device)){
            return AjaxResult.error("设备不存在");
        }
        ShowDeviceShadowRequest request111 = new ShowDeviceShadowRequest();
        request111.setDeviceId(device.getIotId());
        ShowDeviceShadowResponse response = client.showDeviceShadow(request111);
        if (response.getHttpStatusCode() != 200) {
            throw new BaseException("物联网接口 - 获取设备属性，调用失败");
        }

        //将时间转化为localDataTime格式
        // 将时间转换为localDateTime格式
        String eventTime = response.getShadow().get(0).getReported().getEventTime();




        LinkedHashMap<String, Object> properties = (LinkedHashMap<String, Object>) response.getShadow().get(0).getReported().getProperties();
        List<Map<String, Object>> propertyStatusInfo = new ArrayList<>();

        properties.forEach((key, value) -> {
            Map<String, Object> map = new HashMap<>();
            map.put("dataType", type.get(key));
            map.put("identifier", key);
            map.put("name", name.get(key));
            map.put("time", String.valueOf(utcStringToBeijingMillis(eventTime)));
            if(key!="xueyang"){
                map.put("unit",unit.get(key));
            }
            if(key=="HeartRate"){
//                将数据转为int
                double doubleValue = Double.parseDouble(value.toString());
                value = (int) Math.round(doubleValue);
                System.out.println(value);
                map.put("value", value);
            }else {
                map.put("value", value);
            }
            propertyStatusInfo.add(map);
        });
        Map<String, Object> a=propertyStatusInfo.get(1);
        Map<String, Object> b=propertyStatusInfo.get(3);
        propertyStatusInfo.remove(1);
        propertyStatusInfo.add(1,b);
        propertyStatusInfo.remove(3);
        propertyStatusInfo.add(3,a);
        Map<String, List<Map<String, Object>>> map = new HashMap<>();
        map.put("propertyStatusInfo", propertyStatusInfo);
        Map<String, Object> list = new HashMap<>();
        list.put("list",map);


        System.out.println("list = " + list);
        return AjaxResult.success(list);
    }





    public static long utcStringToBeijingMillis(String utcString) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmssX");
        OffsetDateTime odt = OffsetDateTime.parse(utcString, fmt);
        Instant instant = odt.toInstant();
        return instant.toEpochMilli();
    }

    public static String formatBeijing(long epochMillis) {
        ZonedDateTime zdt = Instant.ofEpochMilli(epochMillis).atZone(ZoneId.of("Asia/Shanghai"));
        DateTimeFormatter out = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return zdt.format(out);
    }


    @Autowired
    private IDeviceDataService deviceDataService;
    @Autowired
    private DeviceDataMapper deviceDataManager;
    @Override
    public AjaxResult queryDeviceDataListByDay(ByDayDto dto) {
        Long startTime = dto.getStartTime();
        Long endTime = dto.getEndTime();
        String startTimeStr = formatBeijing(startTime);
        String endTimeStr = formatBeijing(endTime);
//        List<DeviceDataByTime> dataList1 = new ArrayList<>();
//        dataList1 = deviceDataManager.getOneDay(dto);

        List<DeviceData> list = deviceDataService.lambdaQuery()
                .eq(DeviceData::getIotId, dto.getIotId())
                .eq(DeviceData::getFunctionId, dto.getFunctionId())
                .between(DeviceData::getAlarmTime, startTimeStr, endTimeStr)
                .list();
//        if(ObjectUtil.isEmpty( list)){
//            return AjaxResult.error("数据不存在");
//        }
        List<Map<String, Object>> dataList = new ArrayList<>();
        for (int i = 0; i <= 23; i++) {
            double avgValue = 0;
            int count = 0;
            String hour = formatHourToString(i);
            Long endTime1 = startTime + i * 3600000+ 3600000;
            Long startTime1 = startTime + i * 3600000;
            //将startTimeStr1转换成LocalDateTime格式
            LocalDateTime startTimeStr1 = LocalDateTime.parse(formatBeijing(startTime1), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

            LocalDateTime endTimeStr1 = LocalDateTime.parse(formatBeijing(endTime1), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            for (DeviceData deviceData : list) {
                if (deviceData.getAlarmTime().isBefore(endTimeStr1)&&deviceData.getAlarmTime().isAfter(startTimeStr1)) {
                    avgValue += Double.parseDouble(deviceData.getDataValue());
                    count++;
                }
            }
            if(count>0){
                avgValue = avgValue/count;
            }
            Map<String, Object> map = new HashMap<>();
            map.put("dateTime", hour);
            map.put("dataValue", avgValue);
            dataList.add(map);
        }
        return AjaxResult.success(dataList);
    }

    @Override
    public AjaxResult queryDeviceDataListByWeek(ByDayDto dto) {
        String s = formatBeijing(dto.getStartTime());
        //将"yyyy-MM-dd HH:mm:ss"格式的s转换为"yyyy-MM-dd"格式
        s = s.substring(0, 10);

        Map<String, DeviceDataByTime> map = new HashMap<>();
        for (int i = 0; i < 7; i++) {
            DeviceDataByTime deviceDataByTime = new DeviceDataByTime();
            deviceDataByTime.setDateTime(convertToMonthDay(s));
            deviceDataByTime.setDataValue(0);
            map.put(deviceDataByTime.getDateTime(), deviceDataByTime);
            s = LocalDate.parse(s, DateTimeFormatter.ofPattern("yyyy-MM-dd")).plusDays(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        }

        List<DeviceDataByTime> dataList1 = new ArrayList<>();
        dataList1=deviceDataManager.queryDeviceDataListByWeek(dto);

        dataList1.forEach(deviceDataByTime -> {
            System.out.println(deviceDataByTime.toString());
            if (map.containsKey(convertToMonthDay(deviceDataByTime.getDateTime()))) {
                String ss= deviceDataByTime.getDateTime();
                deviceDataByTime.setDateTime(convertToMonthDay(ss));
                System.out.println(deviceDataByTime.toString());
                map.put(deviceDataByTime.getDateTime(),deviceDataByTime);
            }
        });
        List<DeviceDataByTime> dataList = new ArrayList<>();
//        map.forEach((k,v)->{
//            dataList.add(v);
//        });
        //遍历map,按照key从小到大排序加到dataList中
        dataList=map.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .map(Map.Entry::getValue)
                .collect(Collectors.toList());


        return AjaxResult.success(dataList);
    }

    public static String formatHourToString(int hour) {
        if (hour < 0 || hour > 23) {
            throw new IllegalArgumentException("小时必须在0-23之间");
        }
        return String.format("%02d:00", hour);
    }
    public static String convertToMonthDay(String dateStr) {
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("MM.dd");

        LocalDate date = LocalDate.parse(dateStr, inputFormatter);
        return date.format(outputFormatter);
    }
}
